#pragma once

#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <string>
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;
using namespace boost::archive::iterators;

namespace bm
{

inline string base64_encode(const string& input)
{
   typedef base64_from_binary<transform_width<string::const_iterator, 6, 8>> encode_iterator;
   stringstream result;
   try {
      copy(encode_iterator(input.begin()), encode_iterator(input.end()), ostream_iterator<char>(result));
   } catch (...) {
      std::cout << "base64_decode exception" << std::endl;
      return "";
   }
   size_t equal_count = (3 - input.length() % 3) % 3;
   for (size_t i = 0; i < equal_count; i++)
   {
      result.put( '=' );
   }

   return result.str();
}

inline string base64_decode(const string& input)
{
   typedef transform_width<binary_from_base64<string::const_iterator>, 8, 6> decode_iterator;
   stringstream result;
   try {
      copy( decode_iterator(input.begin()), decode_iterator(input.end()), ostream_iterator<char>(result));
   } catch (...) {
      std::cout << "base64_decode exception" << std::endl;
      return "";
   }

   return result.str();
}

}